package com.kefu.exam.service;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kefu.common.context.KefuContext;
import com.kefu.common.exception.BusinessException;
import com.kefu.common.util.JacksonUtil;
import com.kefu.exam.mapper.*;
import com.kefu.exam.model.*;
import com.kefu.exam.vo.*;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import org.springframework.stereotype.Service;
import com.kefu.common.service.AbstractKefuService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author xy
 * @date 2022/02/28
 */
@Service
public class ExamPaperSubjectService extends AbstractKefuService<ExamPaperSubject> {
    @Resource
    protected ExamPaperMapper examPaperMapper;
    @Resource
    protected ExamSubjectMapper examSubjectMapper;
    @Resource
    protected ExamSubjectAnswerMapper examSubjectAnswerMapper;
    @Resource
    protected ExamPaperAnswerMapper examPaperAnswerMapper;
    @Resource
    protected ExamPaperSubjectMapper examPaperSubjectMapper;
    @Resource
    protected ExamCascadeJumpMapper examCascadeJumpMapper;


    public String addPaperSubject(ExamPaperSubjectInsertVo examPaperSubjectVo) {
        ExamPaper paper = examPaperMapper.selectByPrimaryKey(examPaperSubjectVo.getPaperId());
        if (Objects.isNull(paper)) {
            throw BusinessException.msg("问卷已经被删除");
        }
        ExamSubject subject = examSubjectMapper.selectByPrimaryKey(examPaperSubjectVo.getSubjectId());
        if (Objects.isNull(subject) || 0 == subject.getSubjectStatus()) {
            throw BusinessException.msg("问题已经被删除");
        }
        List<ExamPaperSubject> list = examPaperSubjectMapper.selectList(Wrappers.lambdaQuery(ExamPaperSubject.class)
                .eq(ExamPaperSubject::getPaperId, examPaperSubjectVo.getPaperId()).eq(ExamPaperSubject::getSubjectId, examPaperSubjectVo.getSubjectId()));
        if (null != list && list.size() > 0) {
            throw BusinessException.msg("试题已经加入到问卷中");
        }
        ExamPaperSubject info = examPaperSubjectVo.convert();
        info.setPaperName(paper.getPaperName());
        int i = examPaperSubjectMapper.insert(info);
        logger.info("试卷中添加试题 [{}] : {}", i, JacksonUtil.toString(info));
        return examPaperSubjectVo.getPaperId();
    }


    public String batchAdd(String paperId, String subjectIds) {
        if (StrUtil.isBlank(subjectIds)) {
            return paperId;
        }
        ExamPaper info = examPaperMapper.selectByPrimaryKey(paperId);
        if (Objects.isNull(info)) {
            throw BusinessException.msg("问卷不存在");
        }
        String[] subjectList = subjectIds.split(",");
        for (String subjectId :
                subjectList) {
            // 判断问题是否存在
            ExamSubject subject = examSubjectMapper.selectByPrimaryKey(subjectId);
            if (Objects.isNull(subject) || 0 == subject.getSubjectStatus()) {
                logger.info("批量组卷中，问题不存在");
                continue;
            }
            List<ExamPaperSubject> examPaperSubjectList = examPaperSubjectMapper.selectList(Wrappers.lambdaQuery(ExamPaperSubject.class)
                    .eq(ExamPaperSubject::getPaperId, paperId).eq(ExamPaperSubject::getSubjectId, subjectId));
            if (null == examPaperSubjectList || examPaperSubjectList.size() == 0) {
                ExamPaperSubject examPaperSubject = new ExamPaperSubject();
                examPaperSubject.setPaperId(paperId);
                examPaperSubject.setSubjectId(subjectId);
                examPaperSubject.setPaperName(info.getPaperName());
                //查询问卷表内是否已经存在问题
                Long count = examPaperSubjectMapper.selectCount(Wrappers.lambdaQuery(ExamPaperSubject.class)
                        .eq(ExamPaperSubject::getPaperId, paperId));
                //将排序字段赋值插入
                examPaperSubject.setSort(Math.toIntExact(count));
                int i = examPaperSubjectMapper.insert(examPaperSubject);
                logger.info("组卷，组[{}]到试卷[{}]中[{}] : {}", subjectId, info.getPaperName(), i, JacksonUtil.toString(examPaperSubject));
            }
        }
        return paperId;
    }


    public int movingSubject(ExamPaperSubjectSortVo vo) {
        int rows = 0;
        for (int i = 0; i < vo.getSort().length; i++) {
            ExamPaperSubject subject = new ExamPaperSubject();
            subject.setSubjectId(vo.getSort()[i]);
            subject.setSort(i);
            rows += examPaperSubjectMapper.update(subject, Wrappers.lambdaQuery(ExamPaperSubject.class)
                    .eq(ExamPaperSubject::getPaperId, vo.getPaperId())
                    .eq(ExamPaperSubject::getSubjectId, vo.getSort()[i]));
        }
        logger.info("问卷，更新[{}]问卷中[{}]条数据", vo.getPaperId(), rows);
        int delete = examCascadeJumpMapper.delete(Wrappers.lambdaQuery(ExamCascadeJump.class)
                .eq(ExamCascadeJump::getPaperId, vo.getPaperId()));
        logger.info("问卷跳转规则，删除[{}]问卷中[{}]条规则", vo.getPaperId(), delete);
        return rows;
    }


    public void deleteById(String id) {
        ExamPaperSubject info = mapper.selectByPrimaryKey(id);
        if (Objects.isNull(info)) {
            throw BusinessException.msg("问卷问题已经被删除了");
        }
        // 这个组卷关联信息是否被问答过一次
        List<ExamPaperAnswer> list = examPaperAnswerMapper.selectList(Wrappers.lambdaQuery(ExamPaperAnswer.class)
                .eq(ExamPaperAnswer::getPaperId, info.getPaperId()).eq(ExamPaperAnswer::getSubjectId, info.getSubjectId()));
        if (null != list && list.size() > 0) {
            throw BusinessException.msg("当前状态不能删除");
        }
        super.deleteById(id);
    }

    public List<ExamCascadeSubjectVo> searchAllSubject(ExamPaperSubjectSearchVo vo) {

        List<ExamCascadeSubjectVo> list = new ArrayList<>();
        JoinLambdaWrapper<ExamSubject> wrapper = new JoinLambdaWrapper<>(ExamSubject.class);

        wrapper.select(ExamSubject::getFatherSubject, ExamSubject::getSubjectContent, ExamSubject::getSubjectId)
                .eq(ExamSubject::getTenantId, KefuContext.getKefuContext().getTenantId())
                .eq(ExamSubject::getSubjectStatus, 1)
                .and(w -> {
                    w.eq(ExamSubject::getTypeId, 2)
                            .or()
                            .eq(ExamSubject::getTypeId, 3);
                })
                .leftJoin(ExamPaperSubject.class, ExamPaperSubject::getSubjectId, ExamSubject::getSubjectId)
                .select(ExamPaperSubject::getId, ExamPaperSubject::getPaperName, ExamPaperSubject::getPaperId
                        , ExamPaperSubject::getSort)
                .orderBy(true, true, ExamPaperSubject::getSort)
                .end();
        List<ExamCascadeSubjectVo> examPaperSubjectList = examSubjectMapper.joinSelectList(wrapper, ExamCascadeSubjectVo.class);
        List<ExamSubjectAnswer> examSubjectAnswers = examSubjectAnswerMapper.selectList(Wrappers.lambdaQuery(ExamSubjectAnswer.class)
                .and(w -> {
                    examPaperSubjectList.forEach(examPaperSubject -> {
                        w.eq(ExamSubjectAnswer::getSubjectId, examPaperSubject.getSubjectId())
                                .or();
                    });
                })
                .orderBy(true, true, ExamSubjectAnswer::getAnswerSort)
                .eq(ExamSubjectAnswer::getAnswerStatus, 1));
        examPaperSubjectList.forEach(paperSubject -> {
            if (paperSubject.getPaperId() != null && paperSubject.getPaperId().equals(vo.getPaperId())) {
                paperSubject.setSubjectContent("(" + NumberUtil.add(paperSubject.getSort() + 1) + ") " + paperSubject.getSubjectContent());
                list.add(paperSubject);
                ExamPaperSubject i = new ExamPaperSubject();
                i.setSort(1);
                examSubjectAnswers.forEach(subjectAnswer -> {
                    if (subjectAnswer.getSubjectId().equals(paperSubject.getSubjectId())) {
                            examPaperSubjectList.forEach(subject -> {
                                if (subject.getFatherSubject() != null && subject.getFatherSubject().equals(subjectAnswer.getAnswerId())) {
                                    subject.setSubjectContent("(" + NumberUtil.add(paperSubject.getSort() + 1) + "." + i.getSort() + ") " + subject.getSubjectContent());
                                    i.setSort(NumberUtil.add(i.getSort() + 1).intValue());
                                    list.add(subject);
                                }
                            });
                    }
                });
            }
        });

        return list;
    }

    public String[] moveSort(String[] sort, Integer start, Integer end) {
        if (start == end) {
            return sort;
        }
        String startStr = sort[start];
        if (start > end) {
            System.arraycopy(sort, end, sort, end + 1, start - end);
            sort[end] = startStr;
        }
        if (start < end) {
            System.arraycopy(sort, start + 1, sort, start, end - start);
            sort[end] = startStr;
        }
        return sort;
    }
}
